ADFA-4397: Migrate crash and log reporting from Sentry to GlitchTip#1490
ADFA-4397: Migrate crash and log reporting from Sentry to GlitchTip#1490Daniel-ADFA wants to merge 1 commit into
Conversation
Point the Sentry Android SDK at GlitchTip instead of Sentry. The SDK, DSN format, and tooling stay the same; only the endpoint moves. The DSN comes from local.properties for local builds and from CI secrets for release builds, so nothing is hardcoded. - Forward the app's logback output to GlitchTip. WARN and above go to the Logs view; INFO and above ride along as breadcrumbs (breadcrumbs are free). - Tag each event with the device as the user so crashes can be filtered per user. - Drop Sentry features GlitchTip does not support: session replay and profiling (dependency plus manifest flags removed). - Keep event volume inside the 100k plan: error logs no longer become issues (real crashes are still captured), and performance transactions are disabled. Logs bill at 0.1 and share the same event pool.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
📝 Walkthrough
WalkthroughThis PR replaces the Sentry Android session-replay dependency with Sentry Logback integration. It wires a ChangesSentry Logback Migration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant DeviceProtectedApplicationLoader
participant SentryAndroid
participant LoggerContext
participant SentryAppender
participant Sentry
DeviceProtectedApplicationLoader->>SentryAndroid: init(options)
DeviceProtectedApplicationLoader->>LoggerContext: get root logger
DeviceProtectedApplicationLoader->>SentryAppender: configure thresholds and start
DeviceProtectedApplicationLoader->>LoggerContext: attach SentryAppender to root logger
DeviceProtectedApplicationLoader->>Sentry: setUser(ANDROID_ID, MANUFACTURER, MODEL)
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/build.gradle.kts (1)
357-360: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStale comment references removed replay dependency.
The comment above still says "core + replay for quality configuration" but
sentry.android.replaywas removed andsentry.logbackwas added.📝 Proposed fix
- // Sentry Android SDK (core + replay for quality configuration) + // Sentry Android SDK (core + Logback appender for GlitchTip log/breadcrumb forwarding) implementation(libs.sentry.core) implementation(libs.sentry.android.core) implementation(libs.sentry.logback)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/build.gradle.kts` around lines 357 - 360, The dependency block for the Sentry Android SDK has a stale comment that still references replay even though only core, android core, and logback are included now. Update the comment near the Sentry dependency declarations to match the actual set of dependencies in the build script, using the existing Sentry dependency entries as the reference point.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt`:
- Around line 75-97: Wrap the Sentry and Logback initialization in
DeviceProtectedApplicationLoader.load() in a runCatching block so
startup-critical failures do not abort direct-boot setup. Keep the existing
SentryAndroid.init, LoggerContext/SentryAppender configuration, and
Sentry.setUser logic inside the guarded block, and make sure any exception is
swallowed or logged without preventing the later ShizukuSettings.initialize()
and EventBus setup from running.
---
Nitpick comments:
In `@app/build.gradle.kts`:
- Around line 357-360: The dependency block for the Sentry Android SDK has a
stale comment that still references replay even though only core, android core,
and logback are included now. Update the comment near the Sentry dependency
declarations to match the actual set of dependencies in the build script, using
the existing Sentry dependency entries as the reference point.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 79fe817f-c893-4847-8028-6adf51828d4e
📒 Files selected for processing (4)
app/build.gradle.ktsapp/src/main/AndroidManifest.xmlapp/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.ktgradle/libs.versions.toml
| SentryAndroid.init(app) { options -> | ||
| // Reduce replay quality to LOW to prevent OOM | ||
| // This reduces screenshot compression to 10 and bitrate to 50kbps | ||
| // (defaults to MEDIUM quality) | ||
| options.sessionReplay.quality = SentryReplayQuality.LOW | ||
| options.environment = | ||
| if (BuildConfig.DEBUG) IDEApplication.SENTRY_ENV_DEV else IDEApplication.SENTRY_ENV_PROD | ||
| } | ||
|
|
||
| val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext | ||
| val sentryLogAppender = | ||
| SentryAppender().apply { | ||
| context = loggerContext | ||
| setMinimumEventLevel(Level.OFF) | ||
| setMinimumBreadcrumbLevel(Level.INFO) | ||
| setMinimumLevel(Level.WARN) | ||
| start() | ||
| } | ||
| loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(sentryLogAppender) | ||
|
|
||
| Sentry.setUser( | ||
| User().apply { | ||
| id = Settings.Secure.getString(app.contentResolver, Settings.Secure.ANDROID_ID) | ||
| username = "${Build.MANUFACTURER} ${Build.MODEL}" | ||
| }, | ||
| ) | ||
|
|
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File list =="
git ls-files app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
echo
echo "== Outline: DeviceProtectedApplicationLoader.kt =="
ast-grep outline app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt --view expanded || true
echo
echo "== Outline: IDEApplication.kt =="
ast-grep outline app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt --view expanded || true
echo
echo "== Relevant search: runCatching / direct boot / ANR / Sentry =="
rg -n "runCatching|direct boot|ANR|Sentry|LoggerContext|SentryAppender|Settings\.Secure\.ANDROID_ID" app/src/main/java/com/itsaky/androidide/app -SRepository: appdevforall/CodeOnTheGo
Length of output: 6511
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== DeviceProtectedApplicationLoader.kt (lines 50-105) =="
sed -n '50,105p' app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt | cat -n
echo
echo "== IDEApplication.kt (lines 160-185) =="
sed -n '160,185p' app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt | cat -n
echo
echo "== CredentialProtectedApplicationLoader.kt (selected runCatching/Sentry uses) =="
sed -n '130,205p' app/src/main/java/com/itsaky/androidide/app/CredentialProtectedApplicationLoader.kt | cat -nRepository: appdevforall/CodeOnTheGo
Length of output: 6445
🌐 Web query:
Android direct boot Settings.Secure.ANDROID_ID ContentResolver availability
💡 Result:
In Android, Settings.Secure.ANDROID_ID is available to encryption-aware applications during Direct Boot mode [1][2]. Direct Boot mode allows an Android device to boot to a state where it is powered on but the user has not yet entered their credentials (such as a PIN, pattern, or password) [1][3]. To access system resources or perform operations during this phase, an application must be marked as encryption-aware by setting the android:directBootAware attribute to true in its manifest [2][4]. Regarding the specific availability of Settings.Secure.ANDROID_ID and ContentResolver: 1. Settings.Secure.ANDROID_ID: The Settings provider is generally available during Direct Boot, meaning applications can retrieve the ANDROID_ID via the standard ContentResolver interface [5][6]. 2. ContentResolver: While the ContentResolver class is available during Direct Boot, its utility is restricted by the encryption state of the underlying data [2][6]. An encryption-aware app can successfully use a ContentResolver to query data stored in device-encrypted storage [2]. However, attempts to access data in credential-encrypted storage (which is only decrypted after the user unlocks the device) will fail or be unavailable [2]. Developers should ensure that any components interacting with these APIs during the locked state are correctly registered and handle potential limitations regarding data access gracefully [2][4].
Citations:
- 1: https://developer.android.com/privacy-and-security/direct-boot
- 2: https://developer.android.google.cn/privacy-and-security/direct-boot
- 3: https://android-developers.googleblog.com/2016/04/developing-for-direct-boot.html
- 4: https://android.googlesource.com/platform/frameworks/base/+/9bfba9c157e4a5b1325a60d2122be2bf034a5a2a/docs/html/preview/features/direct-boot.jd
- 5: https://android.googlesource.com/platform/frameworks/base/+/97e5130234bcdc1c4a705be4e548302934499bd4/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
- 6: https://pentest.y-security.de/Mobile%20Security%20Testing%20Guide/2021/0x05a-Platform-Overview/
Wrap the Sentry/Logback setup in runCatching.
DeviceProtectedApplicationLoader is startup-critical in direct boot, and any exception here can abort load() before ShizukuSettings.initialize() and EventBus setup. IDEApplication.kt already warns that failures in this loader can lead to ANRs after reboot.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt`
around lines 75 - 97, Wrap the Sentry and Logback initialization in
DeviceProtectedApplicationLoader.load() in a runCatching block so
startup-critical failures do not abort direct-boot setup. Keep the existing
SentryAndroid.init, LoggerContext/SentryAppender configuration, and
Sentry.setUser logic inside the guarded block, and make sure any exception is
swallowed or logged without preventing the later ShizukuSettings.initialize()
and EventBus setup from running.
Point the Sentry Android SDK at GlitchTip instead of Sentry. The SDK, DSN format, and tooling stay the same; only the endpoint moves. The DSN comes from local.properties for local builds and from CI secrets for release builds, so nothing is hardcoded.